﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.OleDb;
using System.Data;
using System.Windows.Controls;
using System.Collections;
using StateGrid.OperationLog;
using StateGrid.User;
using System.IO;
using System.Windows;


namespace StateGrid.MDBservice
{
        /// <summary>
        /// 学位表字段信息类
        /// </summary>
        public class Column
        {
            /// <summary>
            /// 字段名
            /// </summary>
            private String columnName;

            public String ColumnName
            {
                get { return columnName; }
                set { columnName = value; }
            }

       

            /// <summary>
            /// 字段类型
            /// </summary>
            private OleDbType columnType;

            public OleDbType ColumnType
            {
                get { return columnType; }
                set { columnType = value; }
            }



            /// <summary>
            /// 字段长度
            /// </summary>
            private Int32 columnLength;

            public Int32 ColumnLength
            {
                get { return columnLength; }
                set { columnLength = value; }
            }

            /// <summary>
            /// 含有2个参数的构造函数
            /// </summary>
            /// <param name="columnName">字段名</param>
            /// <param name="columnType">字段类型</param>
            public Column(String columnName, OleDbType columnType)
            {
                this.ColumnName = columnName;
                this.ColumnType = columnType;
                this.ColumnLength = 0;
            }
            /// <summary>
            /// 含有3个参数的构造函数
            /// </summary>
            /// <param name="columnName">字段名</param>
            /// <param name="columnType">字段类型</param>
            /// <param name="columnLength">字段长度</param>
            public Column(String columnName, OleDbType columnType, Int32 columnLength)
            {
                this.ColumnName = columnName;
                this.ColumnType = columnType;
                this.ColumnLength = columnLength;
            }

        }

        public class PM
        {

            public Boolean isValid
            {
                get;
                set;
            }
            /// <summary>
            /// 页数
            /// </summary>
            public int ys
            {
                get;
                set;
            }

            public PM()
            {
                isValid = true;
            }

            public virtual String AllContent()
            {
                return String.Empty;
            }

            public virtual void fillEmptyStringAsNull()
            {
            }

            public virtual void eraseNullInEmptyString()
            {
            }
        }

        public class SYML
        {
            public Boolean isValid
            {
                get;
                set;
            }
            public SYML()
            {
                isValid = true;
            }
            public virtual String AllContent()
            {
                return String.Empty;
            }
            public virtual void fillEmptyStringAsNull()
            {
            }
            public virtual void eraseNullInEmptyString()
            {
            }
        }

    public class MDBservice
    {
        /// <summary>
        /// 文库的ID
        /// </summary>
        public virtual String id
        {
            get
            {
                return "";
            }
        }
        protected String serverFileFolder
        {
            get;
            set;
        }
        /// <summary>
        /// 录入数据库的表名
        /// </summary>
        public String pmTableName
        {
            get;
            set;
        }
        /// <summary>
        /// 规范数据所存的表格
        /// </summary>
        public String formatPmTableName
        {
            get;
            set;
        }
        /// <summary>
        /// 是否是从规范化表里读取数据
        /// </summary>
        public Boolean hasFormatTable
        {
            get;
            set;
        }
        /// <summary>
        /// 文库的标题
        /// </summary>
        public String title
        {
            get;
            set;
        }
        /// <summary>
        /// 索引目录表
        /// </summary>
        public String symlTableName
        {
            set;
            get;
        }

        /// <summary>
        /// 表字段信息列表
        /// </summary>
        public List<Column> symlColumnList
        {
            get;
            set;
        }

        /// <summary>
        /// 待入库的索引目录列表
        /// </summary>
        public List<SYML> symlList
        {
            get;
            set;
        }

        /// <summary>
        /// 当前用户对象
        /// </summary>
        public User.User user
        {
            get;
            set;
        }

        /// <summary>
        /// 本地数据库查询语句
        /// 每次使用时指定语句和参数，使用完后清空参数列表
        /// </summary>
        protected OleDbCommand sqlcmd
        {
            get;
            set;
        }
        /// <summary>
        /// 服务器IP地址
        /// </summary>
        protected String serverAddress
        {
            get;
            set;
        }
        protected FtpUpDown FTPtransfer;

        /// <summary>
        /// 丢弃文库前的清理操作
        /// </summary>
        public virtual void clear()
        {
            // TODO: 完成本函数
            if (this.Hash != null)
                this.Hash.Clear();
        }

        /// <summary>
        /// Access数据库路径
        /// </summary>
        private String _dataBasePath;

        public String DataBasePath
        {
            get { return _dataBasePath; }
            set { _dataBasePath = value; this.StrConnection = @"Provider=Microsoft.Jet.OleDb.4.0;Data Source=" + this.DataBasePath; }
        }

        private String _fileFolder;
        /// <summary>
        /// 篇目文件路径
        /// </summary>
        public String fileFolder
        {
            get { return _fileFolder; }
            set { _fileFolder = value + "\\"; }
        }
        /// <summary>
        /// Access数据库连接字符串
        /// </summary>
        public String StrConnection
        {
            get;
            set;
        }

        /// <summary>
        /// Access数据库连接
        /// </summary>
        public OleDbConnection ObjConnection
        {
            get;
            set;
        }

        /// <summary>
        /// 日志操作类
        /// </summary>
        private OperationLog_DAO operationLogDAO;

        /// <summary>
        /// 分类Hashtable
        /// </summary>
        public Hashtable Hash
        {
            get;
            set;
        }
        /// <summary>
        /// 表字段信息列表
        /// </summary>
        private List<Column> columnList;

        internal List<Column> ColumnList
        {
            get { return columnList; }
            set { columnList = value; }
        }

        public List<PM> pmList
        {
            get;
            set;
        }
        /// <summary>
        /// 无参构造函数
        /// </summary>
        public MDBservice()
        {
            serverFileFolder = "D:\\destFiles\\";
            try
            {
                string configFileName = System.Environment.CurrentDirectory + "\\server.config";
                StreamReader sr = new StreamReader(configFileName);
                serverAddress = sr.ReadLine().ToString();
                int index = serverAddress.IndexOf('/');
                string ipAddress;
                if (index >= 0)
                    ipAddress = serverAddress.Substring(0, index);
                else
                    ipAddress = serverAddress;
                String[] nums = ipAddress.Split(".".ToCharArray());
                System.Exception e = new Exception("IP地址错误");
                if (nums.Count() != 4)
                {
                    throw (e);
                }
                foreach (String str in nums)
                {
                    int num = int.Parse(str);
                    if (num < 0 || num > 255)
                    {
                        throw (e);
                    }
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "配置文件错误，程序即将关闭", MessageBoxButton.OK, MessageBoxImage.Error);
                System.Environment.Exit(0);
            }
            FTPtransfer = new FtpUpDown(serverAddress, "administrator", "zyzx@1322");
            
            //获取学位分类表
            sqlcmd = new OleDbCommand();
            sqlcmd.Connection = this.ObjConnection;
            operationLogDAO = new OperationLog_DAO();
        }
        /// <summary>
        /// 有参构造函数
        /// </summary>
        /// <param name="dataBasePath">Access数据库路径</param>
        public MDBservice(String dataBasePath)
        {
            serverFileFolder = "D:\\destFiles\\";
            this.DataBasePath = dataBasePath;
            //this.StrConnection = @"Provider=Microsoft.Jet.OleDb.4.0;Data Source=" + this.DataBasePath;
            //初始化表结构信息
            this.setColumnList();
            //获取学位分类表
            sqlcmd = new OleDbCommand();
            sqlcmd.Connection = this.ObjConnection;
            operationLogDAO = new OperationLog_DAO();
        }

        /// <summary>
        /// 打开Access连接
        /// </summary>
        public void openOleDbConnection()
        {
            if (null == this.ObjConnection)
            {
                //建立连接
                this.ObjConnection = new OleDbConnection(this.StrConnection);
            }
            else if(this.ObjConnection.State==ConnectionState.Closed)
            {
                this.ObjConnection.ConnectionString = this.StrConnection;
            }
            if (this.ObjConnection.State != ConnectionState.Open)
            {
                //打开连接
                this.ObjConnection.Open();
            }    
        }

        /// <summary>
        /// 关闭Access连接
        /// </summary>
        public void closeOleDbConnection()
        {
            if (null == this.ObjConnection)
            {
                return;
            }
            if (this.ObjConnection.State != ConnectionState.Closed)
            {
                this.ObjConnection.Close();
            }
        }

        public virtual String getTest()
        {
            return "这是用来测试SQLserver数据库连接是否正确的函数";
        }

        public void logInfo(ScrollViewer logViewer, String err)
        {
            logViewer.Dispatcher.Invoke(new Action(() => { logViewer.Content += err; }));
        }

        public void setBarValue(ProgressBar pgBar, double aValue)
        {
            pgBar.Dispatcher.Invoke(new Action(() => { pgBar.Value = aValue; }));
        }

        public virtual void setColumnList()
        {
            MessageBox.Show("setColumnList 未实现", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
        }

        /// <summary>
        /// 在getPMList中调用，被子类重载
        /// 获取每一条篇目信息
        /// </summary>
        /// <param name="reader"></param>
        /// <returns>篇目信息</returns>
        protected virtual PM getPM(OleDbDataReader reader, out String err)
        {
            MessageBox.Show("getPM 未实现", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            err = String.Empty;
            return null;
        }

        /// <summary>
        /// 在getSymlList中调用，被子类重载
        /// 获取每一条索引目录信息
        /// </summary>
        /// <param name="reader"></param>
        /// <returns>索引目录信息</returns>
        protected virtual SYML getSyml(OleDbDataReader reader, out String err)
        {
            MessageBox.Show("getSyml 未实现", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            err = String.Empty;
            return null;
        }

        /// <summary>
        /// 处理出错的篇名信息
        /// </summary>
        /// <param name="pm">出错的篇名信息</param>
        /// <param name="errMsg">出错提示信息</param>
        public void handleWrongPM(PM pm, String errMsg, ScrollViewer logViewer)
        {
            pm.isValid = false;
            logInfo(logViewer, errMsg);
        }

        /// <summary>
        /// 处理出错的索引目录信息
        /// </summary>
        /// <param name="syml">出错的索引信息</param>
        /// <param name="errMsg">出错提示信息</param>
        public void handleWrongSyml(SYML syml, String errMsg, ScrollViewer logViewer)
        {
            syml.isValid = false;
            logInfo(logViewer, errMsg);
        }

        /// <summary>
        /// 读取所有篇目列表
        /// </summary>
        /// <returns>篇目列表</returns>
        public void getPMList(ScrollViewer logViewer)
        {
            if (pmList == null)
                pmList = new List<PM>();
            pmList.Clear();
            //打开连接
            this.openOleDbConnection();

            logInfo(logViewer, "正在读取数据，请耐心等候\n");
            //sql语句
            sqlcmd.CommandText = @"select * from " + (hasFormatTable? formatPmTableName : pmTableName);
            sqlcmd.Connection = this.ObjConnection;
            //OleDbCommand sqlcmd = new OleDbCommand(@"select * from " + (hasFormatTable? formatPmTableName : pmTableName), this.ObjConnection);
            //执行查询
            OleDbDataReader reader = null;
            try
            {
                reader = sqlcmd.ExecuteReader();
            }
            catch (Exception e)
            {
                logInfo(logViewer, e.Message);
            }
            while (reader.Read())
            { //这个read调用很重要！不写的话运行时将提示找不到数据
                String err;
                PM pm = getPM(reader, out err);

                if (!String.Empty.Equals(err))
                {
                    logInfo(logViewer, err);
                    pm.isValid = false;
                }
                pmList.Add(pm);
            }
            reader.Close();
            this.closeOleDbConnection();
            logInfo(logViewer, "读取数据完毕，进行规范化处理\n");
            return;
        }

        /// <summary>
        /// 读取所有索引目录列表
        /// </summary>
        /// <returns>索引目录列表</returns>
        public void getSymlList(ScrollViewer logViewer)
        {
            if (symlList == null)
                symlList = new List<SYML>();
            symlList.Clear();
            //打开连接
            this.openOleDbConnection();

            //sql语句
            sqlcmd.CommandText = @"select * from " + symlTableName;
            sqlcmd.Connection = this.ObjConnection;
            //执行查询
            OleDbDataReader reader = sqlcmd.ExecuteReader();
            while (reader.Read())
            { //这个read调用很重要！不写的话运行时将提示找不到数据
                String err;
                SYML syml = getSyml(reader, out err);

                if (!String.Empty.Equals(err))
                {
                    logInfo(logViewer, err);
                    syml.isValid = false;
                }
                symlList.Add(syml);
            }
            reader.Close();
            this.closeOleDbConnection();
            return;
        }

        public virtual Boolean checkPMValid(PM pm, out String errMsg)
        {
            MessageBox.Show("checkPMValid 未实现", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            errMsg = String.Empty;
            return true;
        }

        public virtual Boolean checkSymlValid(SYML syml, out String errMsg)
        {
            MessageBox.Show("checkSymlValid 未实现", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            errMsg = String.Empty;
            return true;
        }

        public void checkPMList(ScrollViewer logViewer)
        {
            if (pmList == null)
                pmList = new List<PM>();
            this.openOleDbConnection();

            foreach (PM pm in pmList)
            {
                if (pm.isValid)
                {
                    String err;
                    pm.isValid = checkPMValid(pm, out err);
                    if (!String.Empty.Equals(err))
                    {
                        logInfo(logViewer, err);
                    }
                }
            }
        }

        public void checkSymlList(ScrollViewer logViewer)
        {
            if (symlList == null)
                symlList = new List<SYML>();
            this.openOleDbConnection();

            foreach (SYML syml in symlList)
            {
                if (syml.isValid)
                {
                    String err;
                    syml.isValid = checkSymlValid(syml, out err);
                    if (!String.Empty.Equals(err))
                    {
                        logInfo(logViewer, err);
                    }
                }
            }
        }

        /// <summary>
        /// 获取分类编码、索引编码等信息的hashtable
        /// </summary>
        public virtual String getHash()
        {
            return String.Empty;
        }

        /// <summary>
        /// 检查表名aTableName是否存在
        /// </summary>
        /// <param name="aTableName">要检查的表名</param>
        /// <returns>空值表示存在，非空为错误信息</returns>
        public String validateTableName(String aTableName, String aDataBasePath = null, String aFileFolder = null)
        {
            String result = "对不起，您所选的数据库中不存在表名为：“" + aTableName + "”的表！！！\n";
            //设置连接
            if (aDataBasePath != null)
                this.DataBasePath = aDataBasePath;
            if (aFileFolder != null)
                this.fileFolder = aFileFolder;
            //建立连接
            this.openOleDbConnection();

            //获取数据库中的表名
            DataTable shemaTable = this.ObjConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new Object[] { null, null, null, "TABLE" });

            //获取记录总行数
            int count = shemaTable.Rows.Count;
            //获取表名是第几列
            int column = shemaTable.Columns.IndexOf("TABLE_NAME");
            for (int i = 0; i < count; i++)
            {
                DataRow dataRow = shemaTable.Rows[i];
                if (dataRow.ItemArray.GetValue(column).ToString().ToUpper().Equals(aTableName))
                {
                    result = String.Empty;
                    break;
                }
            }
            //this.closeOleDbConnection();
            return result;
        }

        /// <summary>
        /// 验证表中字段是否全部有效
        /// </summary>
        /// <returns>空表示执行正确，非空为出错信息</returns>
        public List<ColumnError> validateTableColums(Boolean isPmTable = true)
        {
            List<ColumnError> result = new List<ColumnError>();
            //打开Access数据库连接
            this.openOleDbConnection();
            //初始化表结构信息
            this.setColumnList();

            String tableName;
            List<Column> columnList;
            if (isPmTable)
            {
                tableName = (hasFormatTable ? formatPmTableName : pmTableName);
                columnList = this.ColumnList;
            }
            else
            {
                tableName = symlTableName;
                columnList = this.symlColumnList;
            }
            //获取数据库中的字段名
            DataTable columnsTable = this.ObjConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new Object[] { null, null, tableName, null });
            int count = columnsTable.Rows.Count;
            int nameColumn = columnsTable.Columns.IndexOf("COLUMN_NAME");
            int typeColumn = columnsTable.Columns.IndexOf("DATA_TYPE");
            int lengthColumn = columnsTable.Columns.IndexOf("CHARACTER_MAXIMUM_LENGTH");


            ColumnError error = null;
            foreach (Column tempColumn in columnList)
            {
                Boolean flag = true;
                for (int i = 0; i < count; i++)
                {
                    DataRow dataRow = columnsTable.Rows[i];
                    //获取字段类型
                    OleDbType type = (OleDbType)dataRow.ItemArray.GetValue(typeColumn);
                    //获取字段名称
                    String name = dataRow.ItemArray.GetValue(nameColumn).ToString();
                    //如果类型为Date或字段长度为0，则找到匹配；否则，继续判断字段长度
                    if (tempColumn.ColumnName.Equals(name))
                    {
                        flag = false;
                        if (tempColumn.ColumnType == type)
                        {
                            Int32 length;
                            Int32.TryParse(dataRow.ItemArray.GetValue(lengthColumn).ToString(), out length);
                            if (tempColumn.ColumnType == OleDbType.Date || tempColumn.ColumnLength == 0 || tempColumn.ColumnLength == length)
                            {
                                break;
                            }
                            else
                            {
                                error = new ColumnError();
                                error.Column = tempColumn.ColumnName;
                                error.Error = "实际字段长度为" + tempColumn.ColumnLength + "；而给出的字段长度为" + length;
                            }
                        }
                        else
                        {
                            error = new ColumnError();
                            error.Column = tempColumn.ColumnName;
                            error.Error = "实际类型为" + tempColumn.ColumnType + "；而给出的字段长度为" + type;
                        }
                        result.Add(error);
                        break;
                    }
                }
                if (flag)
                {
                    error = new ColumnError();
                    error.Column = tempColumn.ColumnName;
                    error.Error = "没有找到该字段";
                    result.Add(error);
                }
            }
            this.closeOleDbConnection();
            return result;
        }

        /// <summary>
        /// 规整字段
        /// </summary>
        /// <param name="pm">要规整的记录</param>
        /// <returns>反馈规整信息，规整错误</returns>
        public virtual String formatData(PM pm)
        {
            MessageBox.Show("formatData 未实现", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            return null;
        }

        public bool formatData(ScrollViewer logViewer, ProgressBar pgBar)
        {
            String err;
            this.getPMList(logViewer);
            err = this.getHash();
            if (!String.Empty.Equals(err))
            {
                logInfo(logViewer, err);
                return false;
            }
            logInfo(logViewer, "正在规范内容\n");
            setBarValue(pgBar, 0);
            int count = pmList.Count;
            int i = 0;
            foreach (PM pm in pmList)
            {
                err = formatData(pm);
                if (!String.Empty.Equals(err))
                    handleWrongPM(pm, err, logViewer);
                err = updatePM(pm);
                if (!String.Empty.Equals(err))
                    logInfo(logViewer, err);
                i++;
                setBarValue(pgBar, i / (double)count);
            }
            setBarValue(pgBar, 0);
            return true;
        }

        /// <summary>
        /// 规整字段
        /// </summary>
        /// <param name="pm">要规整的记录</param>
        /// <returns>反馈规整信息，规整错误</returns>
        public virtual String formatSyml(SYML syml)
        {
            MessageBox.Show("formatSyml 未实现", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            return null;
        }

        public bool formatSyml(ScrollViewer logViewer, ProgressBar pgBar)
        {
            String err;
            this.getSymlList(logViewer);
//            err = this.getHash();   //TODO:
//            if (!String.Empty.Equals(err))
//            {
//                logInfo(logViewer, err);
//                return false;
//            }
            logInfo(logViewer, "正在规范索引目录内容\n");
            setBarValue(pgBar, 0);
            int count = symlList.Count;
            int i = 0;
            foreach (SYML syml in symlList)
            {
                err = formatSyml(syml);
                if (!String.Empty.Equals(err))
                    handleWrongSyml(syml, err, logViewer);
                err = updateSyml(syml);
                if (!String.Empty.Equals(err))
                    logInfo(logViewer, err);
                i++;
                setBarValue(pgBar, i / (double)count);
            }
            setBarValue(pgBar, 0);
            return true;
        }

        /// <summary>
        /// 在本地添加一条记录
        /// </summary>
        /// <param name="pm"></param>
        /// <returns>空表示执行成功，非空表示执行失败的信息</returns>
        public virtual String insertPM(PM pm)
        {
            MessageBox.Show("insertPM 未实现", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            return null;
        }

        /// <summary>
        /// 在本地添加一条索引目录记录
        /// </summary>
        /// <param name="syml">所要添加的索引目录信息</param>
        /// <returns>空表示执行成功，非空表示执行失败的信息</returns>
        public virtual String insertSyml(SYML syml)
        {
            MessageBox.Show("insertSyml 未实现", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            return null;
        }

        /// <summary>
        /// 在本地删除一条记录
        /// </summary>
        /// <param name="pm"></param>
        /// <returns></returns>
        public virtual int deletePM(PM pm, out String err)
        {
            MessageBox.Show("deletePM 未实现", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            err = String.Empty;
            return 0;
        }
        /// <summary>
        /// 在本地删除一条记录
        /// </summary>
        /// <param name="pm"></param>
        /// <returns></returns>
        public virtual int deleteSyml(SYML syml, out String err)
        {
            MessageBox.Show("deleteSyml 未实现", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            err = String.Empty;
            return 0;
        }

        /// <summary>
        /// 在本地更新一条记录
        /// </summary>
        /// <param name="xw">要更新的学位论文信息</param>
        /// <returns>更新结果，true更新成功；false更新成功</returns>
        public String updatePM(PM pm)
        {
            // 另一种方法是先delete再insert，就不用每文库都写了
            String err;
            deletePM(pm, out err);
            err += insertPM(pm);
            return err;
        }

        /// <summary>
        /// 在本地更新一条索引记录
        /// </summary>
        /// <param name="syml">要更新的索引目录信息</param>
        /// <returns>更新结果，空更新成功；非空新成功</returns>
        public String updateSyml(SYML syml)
        {
            // 另一种方法是先delete再insert，就不用每文库都写了
            String err;
            deleteSyml(syml, out err);
            err += insertSyml(syml);
            return err;
        }

        /// <summary>
        /// 本地Access库去重
        /// 方案：对每PM，先delete再insert，最后更新下PMList即可。可能会慢点没关系。
        ///         这样只需要写一个delete一个insert
        /// </summary>
        public void removeLocalDuplicate(ScrollViewer logViewer, ProgressBar pgBar)
        {
            String err;
            int count = pmList.Count;
            int i = 0;
            logInfo(logViewer, "正在本地去重\n");
            setBarValue(pgBar, 0);
            foreach (PM pm in pmList)
            {
                i++;
                setBarValue(pgBar, i / (double)count);
                if (!pm.isValid)
                    continue;
                int cnt = deletePM(pm, out err);
                if (!err.Equals(String.Empty))
                    logInfo(logViewer, err);
                if (cnt > 1)
                {
                    logInfo(logViewer, "有" + cnt.ToString() + "条重复的信息：" + pm.ToString() + "\n");
                }
                err = insertPM(pm);
                if (!String.Empty.Equals(err))
                    logInfo(logViewer, err);
            }
            checkPMList(logViewer);
            setBarValue(pgBar, 0);
        }

        public void removeLocalSymlDuplicate(ScrollViewer logViewer, ProgressBar pgBar)
        {
            String err;
            int count = symlList.Count;
            int i = 0;
            logInfo(logViewer, "正在本地去重索引编码\n");
            setBarValue(pgBar, 0);
            foreach (SYML syml in symlList)
            {
                i++;
                setBarValue(pgBar, i / (double)count);
                if (!syml.isValid)
                    continue;
                int cnt = deleteSyml(syml, out err);
                if (!err.Equals(String.Empty))
                    logInfo(logViewer, err);
                if (cnt > 1)
                {
                    logInfo(logViewer, "有" + cnt.ToString() + "条重复的信息：" + syml.ToString() + "\n");
                }
                err = insertSyml(syml);
                if (!String.Empty.Equals(err))
                    logInfo(logViewer, err);
            }
            checkSymlList(logViewer);
            setBarValue(pgBar, 0);
        }

        /// <summary>
        /// 主库查重
        /// </summary>
        /// <param name="xw"></param>
        /// <returns>true:说明主库中已存在该记录；false:说明主库中不存在该记录</returns>
        public virtual Boolean findServerDuplicate(PM pm)
        {
            MessageBox.Show("findServerDuplicate 未实现", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            return false;
        }

        public virtual Boolean findServerSymlDuplicate(SYML syml)
        {
            MessageBox.Show("findServerSymlDuplicate 未实现", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            return false;
        }

        /// <summary>
        /// 主库去重
        /// </summary>
        /// <returns></returns>
        public void removeServerDuplicate(ScrollViewer logViewer, ProgressBar pgBar)
        {
            String err;
            int count = pmList.Count;
            int i = 0;
            logInfo(logViewer, "正在执行主库查重操作\n");
            setBarValue(pgBar, 0);
            foreach (PM pm in pmList)
            {
                i++;
                setBarValue(pgBar, i / (double)count);
                if (!pm.isValid)
                    continue;
                if (findServerDuplicate(pm))
                {
                    logInfo(logViewer, "此条目在主库中已存在: " + pm.ToString() + "\n");
                    pm.isValid = false;
                    deletePM(pm, out err);
                    if (!String.Empty.Equals(err))
                        logInfo(logViewer, err);
                }
            }
            setBarValue(pgBar, 0);
        }

        public void removeServerSymlDuplicate(ScrollViewer logViewer, ProgressBar pgBar)
        {
            String err;
            int count = symlList.Count;
            int i = 0;
            logInfo(logViewer, "正在执行索引目录的主库查重操作\n");
            setBarValue(pgBar, 0);
            foreach (SYML syml in symlList)
            {
                i++;
                setBarValue(pgBar, i / (double)count);
                if (!syml.isValid)
                    continue;
                if (findServerSymlDuplicate(syml))
                {
                    logInfo(logViewer, "此条目在主库中已存在: " + syml.ToString() + "\n");
                    syml.isValid = false;
                    deleteSyml(syml, out err);
                    if (!String.Empty.Equals(err))
                        logInfo(logViewer, err);
                }
            }
            setBarValue(pgBar, 0);
        }

        public virtual String addOneRecord(PM pm)
        {
            MessageBox.Show("addOneRecord 未实现", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            return String.Empty;
        }

        public void addRecords(ScrollViewer logViewer, ProgressBar pgBar)
        {
            int count = pmList.Count;
            int i = 0;
            logInfo(logViewer, "正在上传数据\n");
            setBarValue(pgBar, 0);
            foreach (PM pm in pmList)
            {
                i++;
                setBarValue(pgBar, i / (double)count);
                if (!pm.isValid)
                    continue;
                String err;
                err = addOneRecord(pm);
                if (!err.Equals(String.Empty))
                {
                    logInfo(logViewer, err);
                }
                else
                {
                    deletePM(pm, out err);
                    if (!String.Empty.Equals(err))
                        logInfo(logViewer, err);
                }
                //更新年份区间
            }
            setBarValue(pgBar, 0);
        }
        public virtual String addOneSymlRecord(SYML syml)
        {
            MessageBox.Show("addOneSymlRecord 未实现", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            return String.Empty;
        }

        public void addSymlRecords(ScrollViewer logViewer, ProgressBar pgBar)
        {
            int count = symlList.Count;
            int i = 0;
            logInfo(logViewer, "正在上传索引目录\n");
            setBarValue(pgBar, 0);
            foreach (SYML syml in symlList)
            {
                i++;
                setBarValue(pgBar, i / (double)count);
                if (!syml.isValid)
                    continue;
                String err;
                err = addOneSymlRecord(syml);
                if (!err.Equals(String.Empty))
                {
                    logInfo(logViewer, err);
                }
                else
                {
                    deleteSyml(syml, out err);
                    if (!String.Empty.Equals(err))
                        logInfo(logViewer, err);
                }
                //更新年份区间
            }
            setBarValue(pgBar, 0);
        }
        public virtual String insertPMwithUpdateWJM(PM pm)
        {
            MessageBox.Show("insertPMwithUpdateWJM 未实现", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            return String.Empty;
        }
        public virtual String insertSymlwithUpdateSybm(SYML syml)
        {
            MessageBox.Show("insertSymlwithUpdateSybm 未实现", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            return String.Empty;
        }
    }
}
